package com.apiserver.kernel.utils;


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;


/**
 * 
 * @ClassName ReflectUtil
 * @Description TODO(反射工具)
 * @author feizhou
 * @Date 2018年5月23日 下午3:16:51
 * @version 1.0.0
 */
public class ReflectUtil{
    /**
     *
     * @Description (设置obj对象fieldName的属性值,fieldName为基本数据类型)
     * @author feizhou
     * @Date 2018年5月23日下午3:52:31
     * @version 1.0.0
     * @param obj
     * @param fieldName
     * @param value
     * @return false:没有这个字段,ture:设置值成功
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static boolean setProperty(Object obj, String fieldName,Object value){
        try
        {
            Field field = obj.getClass().getDeclaredField(fieldName);
            Type t = field.getGenericType();
            if (field.isAccessible())
            {
                // 获取此对象的 accessible 标志的值。
                // 将指定对象变量上此 Field 对象表示的字段设置为指定的新值
                field.set(obj, value);
            } else{
                Class typeClass = field.getType();
                Constructor con = typeClass.getConstructor(value.getClass());
                Object newInstance = con.newInstance(value);

                field.setAccessible(true);
                field.set(obj, newInstance);
                field.setAccessible(false);
            }
            return true;
        } catch (Exception e)
        {

        }
        return false;
    }


    /**
     *  
     * 描述：调用对象的方法
     * @author： feizhou
     * @date ：2019/1/7 17:13
     * @param ：[obj, methodName, paramValues, parameterType]
     * @return java.lang.String
     */
    public static String getMethod(Object obj, String methodName,Object  paramValues,Class  parameterType) {
        String valueString = "";
        try {
                //获取方法
                Method method = obj.getClass().getDeclaredMethod(methodName,parameterType);
                Object result = method.invoke(obj,paramValues);
                if (result != null) {
                    valueString = result.toString().trim();
                }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return valueString;
    }

    /**
     * 
     * @Description (获取obj对象fieldName的属性值)
     * @author feizhou
     * @Date 2018年5月23日下午3:47:43  
     * @version 1.0.0
     * @param obj
     * @param fieldName
     * @return
     */
    public static Object getProperty(Object obj, String fieldName) {
        Object value = null;
        try
        {
            Field field = getFieldByFieldName(obj, fieldName);
            if (field != null)
            {	
            	//该field是否可以访问
                if (field.isAccessible())
                {
                    value = field.get(obj);
                } else
                {
                    //设置可以强制访问，如private 类型的属性
                    field.setAccessible(true);
                    value = field.get(obj);
                    field.setAccessible(false);
                }
            }
        } catch (Exception e)
        {
        }
        return value;
    }
    /**
     *
     * @Description (获取obj对象fieldName的Field对象)
     * @author feizhou
     * @Date 2018年5月23日下午3:48:14
     * @version 1.0.0
     * @param obj
     * @param fieldName
     * @return
     * 如：private java.lang.String com.feizhou.common.tools.reflect.User.name
     */
    public static Field getFieldByFieldName(Object obj, String fieldName)
    {
        if (obj == null || fieldName == null)
        {
            return null;
        }
        Class<?> superClass = obj.getClass();
        for (; superClass != Object.class; superClass = superClass.getSuperclass())
        {
            try
            {
                return superClass.getDeclaredField(fieldName);
            } catch (Exception e)
            {
            }
        }
        return null;
    }


    /**
     *
     * @Description (获取接口对象的所有字段对应的值和字段Map(值，字段名))
     * @author feizhou
     * @Date 2018年6月12日上午11:18:19
     * @version 1.0.0
     * @param  object
     * @return
     */
    public  static Map<String,String>  getClassValueToProperty(Object object) throws IllegalAccessException {

        Map<String,String> map=new HashMap<String, String>();
        // 拿到该类
        Class<?> clz = object.getClass();
        // 获取实体类的所有属性，返回Field数组
        Field[] fields = clz.getDeclaredFields();
        Object   val=null;
            for (Field field : fields) {
                // 设置些属性是可以访问的
                field.setAccessible(true);
                val = field.get(object);
                map.put(String.valueOf(val), field.getName());
            }
        return map;
    }
    /**
     *
     * @Description (获取接口对象的所有字段对应的字段和值Map(字段名，值))
     * @author feizhou
     * @Date 2018年6月12日上午11:18:19
     * @version 1.0.0
     * @param  object
     * @return
     */
    public  static Map<String,String>  getClassPropertyToValue(Object object) throws IllegalAccessException {

        Map<String,String> map=new HashMap<String, String>();
        // 拿到该类
        Class<?> clz = object.getClass();
        // 获取实体类的所有属性，返回Field数组
        Field[] fields = clz.getDeclaredFields();
        Object   val=null;
        for (Field field : fields) {
            // 设置些属性是可以访问的
            field.setAccessible(true);
            val = field.get(object);
            map.put( field.getName(),String.valueOf(val));
        }
        return map;
    }
}
